package study.itwill.jsp;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class ImageUtil {
	private static ImageUtil current = null;

	public static final int RATIO = 0;
	public static final int SAME = -1;

	public static ImageUtil getInstance() {
		if (current == null) {
			current = new ImageUtil();
		}
		return current;
	}

	/**
	 * 이미지를 리사이즈하여 복사본을 저장한다.
	 * @param srcPath - 원본 이미지의 경로
	 * @param destPath - 복사본이 저장될 경로
	 * @param width - 리사이즈될 넓이 (0으로 지정될 경우, 높이값에 따라서 비율적으로 변경된다.)
	 * @param height - 리사이즈될 높이 (0으로 지정될 경우, 넓이값에 따라서 비율적으로 변경된다.)
	 */
	public void resize(String srcPath, String destPath, int width, int height) {
		// 원본 이미지의 객체
		Image srcImg = null;

		// 원본파일
		File src = new File(srcPath);
		// 대상파일
		File dest = new File(destPath);

		// 확장자
		String suffix = src.getName()
				.substring(src.getName().lastIndexOf('.') + 1).toLowerCase();

		try {
			/** 이미지 읽어들이기 */
			if (suffix.equals("bmp") || suffix.equals("png")
					|| suffix.equals("gif")) {
				srcImg = ImageIO.read(src);
			} else {
				// BMP가 아닌 경우 ImageIcon을 활용해서 Image 생성
				// 이렇게 하는 이유는 getScaledInstance를 통해 구한 이미지를
				// PixelGrabber.grabPixels로 리사이즈 할때
				// 빠르게 처리하기 위함이다.
				srcImg = new ImageIcon(src.toURI().toURL()).getImage();
			}

			// 원본 이미지의 크기
			int srcWidth = srcImg.getWidth(null);
			int srcHeight = srcImg.getHeight(null);

			// 대상 이미지의 크기
			int destWidth = -1, destHeight = -1;

			// 크기가 주어지지 않은 경우
			if (width == SAME) {
				destWidth = srcWidth;
			} else if (width > 0) {
				destWidth = width;
			}

			if (height == SAME) {
				destHeight = srcHeight;
			} else if (height > 0) {
				destHeight = height;
			}

			if (width == RATIO && height == RATIO) {
				destWidth = srcWidth;
				destHeight = srcHeight;
			} else if (width == RATIO) {
				double ratio = ((double) destHeight) / ((double) srcHeight);
				destWidth = (int) ((double) srcWidth * ratio);
			} else if (height == RATIO) {
				double ratio = ((double) destWidth) / ((double) srcWidth);
				destHeight = (int) ((double) srcHeight * ratio);
			}

			Image imgTarget = srcImg.getScaledInstance(destWidth, destHeight,
					Image.SCALE_SMOOTH);
			int pixels[] = new int[destWidth * destHeight];
			PixelGrabber pg = new PixelGrabber(imgTarget, 0, 0, destWidth,
					destHeight, pixels, 0, destWidth);
			pg.grabPixels();
			BufferedImage destImg = new BufferedImage(destWidth, destHeight,
					BufferedImage.TYPE_INT_RGB);
			destImg.setRGB(0, 0, destWidth, destHeight, pixels, 0, destWidth);

			//ImageIO.write(destImg, "jpg", dest);
			saveJPEG(destImg, dest, 100.0f);
		} catch (IOException e) {
		} catch (InterruptedException e) {
		} catch (Exception e) {
		}
	}

	private void saveJPEG(BufferedImage thumbImage, File out, double compression) throws IOException {
		OutputStream os = new FileOutputStream(out);
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
		JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);
		compression = Math.max(0, Math.min(compression, 100));
		param.setQuality((float) compression / 100.0f, false);
		encoder.setJPEGEncodeParam(param);
		encoder.encode(thumbImage);
		os.close();
	}
}